package com.itic.appbase.framework.utils;

import java.util.Calendar;
import java.util.Date;

/**
 * 日历工具类
 * <p>Company: itic</p>
 * 
 * @author: zhaokechun
 * @date: 2015年5月7日 下午1:13:40
 * @version: V1.0
 */
public class CalendarHelper {
    private CalendarHelper() {
        super();
    }

    /**
     * 判断2个日期是否在同一周内.
     * 
     * @see #isInSameWeek(Calendar cal1, Calendar cal2)
     * @param date1 日期1
     * @param date2 另一个日期
     * @return 若在同一周则返回false, 不在同一周或任意日期为空则返回false
     */
    public static boolean isInSameWeek(Date date1, Date date2) {
        if (date1 == null || date2 == null) {
            return false;
        }
        Calendar cal1 = Calendar.getInstance();
        Calendar cal2 = Calendar.getInstance();
        cal1.setTime(date1);
        cal2.setTime(date2);
        return isInSameWeek(cal1, cal2);
    }

    /**
     * 判断2个日期是否在同一周内.
     * 
     * @param cal1 日期1
     * @param cal2 另一个日期
     * @return 若在同一周则返回false, 不在同一周或任意日期为空则返回false
     */
    public static boolean isInSameWeek(Calendar cal1, Calendar cal2) {
        Calendar monday = getDayOfWeek(cal1, 1);
        Calendar sunday = getDayOfWeek(cal1, 7);
        sunday.set(sunday.get(Calendar.YEAR), sunday.get(Calendar.MONTH), sunday.get(Calendar.DATE), 23, 59, 59);
        return cal2.compareTo(monday) >= 0 && cal2.compareTo(sunday) <= 0;
    }

    /**
     * 获取指定日期所在周的任意一天.
     * <p>传入指定日期,及该星期指定的某一天.（星期一传1,星期天传7）
     * <p>例如：
     * <p>获取本周的礼拜五
     * <br/>
     * <br/>Calendar cal = Calendar.getInstance();
     * <br/>cal.setTime(new Date());
     * <br/>getDayOfWeek(cal,5);
     * 
     * <p>返回日期的准确时间为该天的零点,精确到毫秒,如 2014-10-01 00:00:00 000,
     * 
     * @param c 指定日期
     * @param num 该星期指定的某一天
     * @return 指定的日期
     */
    public static Calendar getDayOfWeek(Calendar c, int num) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(c.getTime());
        int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (dayOfWeek == 0) {
            dayOfWeek = 7;
        }
        cal.add(Calendar.DATE, -dayOfWeek + num);
        cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DATE), 0, 0, 0);
        long mills = cal.getTimeInMillis() / 1000;
        cal.setTimeInMillis(mills * 1000); // 忽略毫秒数
        return cal;
    }

    /**
     * 获取指定日期所在周的任意一天.
     * 
     * @see #getDayOfWeek(Calendar c,int num)
     * @param date
     * @param num
     * @return
     */
    public static Date getDayOfWeek(Date date, int num) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return getDayOfWeek(cal, num).getTime();
    }

    /**
     * 判断指定日期是否为周末（周六/周日）.
     * 
     * @param cal
     * @return 若传入日期为周六/周日返回true,否则返回false
     */
    public static boolean isWeekEnd(Calendar cal) {
        int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
        return dayOfWeek == Calendar.SATURDAY || dayOfWeek == Calendar.SUNDAY;
    }

    /**
     * 判断两日期是否是同一天.
     * 
     * @param date1
     * @param date2
     * @return 为同一天 返回true,否则返回false
     */
    public static boolean isSameDay(Date date1, Date date2) {
        if (date1 == null || date2 == null) {
            return false;
        }
        Calendar cal1 = Calendar.getInstance();
        Calendar cal2 = Calendar.getInstance();
        cal1.setTime(date1);
        cal2.setTime(date2);
        return isSameDay(cal1, cal2);
    }

    /**
     * 判断两日期是否是同一天.
     * 
     * @see isSameDay(Date date1,Date date2)
     * @param cal1
     * @param cal2
     * @return
     */
    public static boolean isSameDay(Calendar cal1, Calendar cal2) {
        if (cal1 == null || cal2 == null) {
            return false;
        } else {
            return cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR)
                    && cal1.get(Calendar.MONTH) == cal2.get(Calendar.MONTH)
                    && cal1.get(Calendar.DATE) == cal2.get(Calendar.DATE);
        }
    }

    /**
     * 获取两个日期的间隔天数.
     * 
     * @param startDate
     * @param endDate
     * @return 两个日期的间隔天数
     */
    public static Integer getDaysBetween(Date startDate, Date endDate) {
        Calendar fromCalendar = Calendar.getInstance();
        fromCalendar.setTime(startDate);
        fromCalendar.set(Calendar.HOUR_OF_DAY, 0);
        fromCalendar.set(Calendar.MINUTE, 0);
        fromCalendar.set(Calendar.SECOND, 0);
        fromCalendar.set(Calendar.MILLISECOND, 0);

        Calendar toCalendar = Calendar.getInstance();
        toCalendar.setTime(endDate);
        toCalendar.set(Calendar.HOUR_OF_DAY, 0);
        toCalendar.set(Calendar.MINUTE, 0);
        toCalendar.set(Calendar.SECOND, 0);
        toCalendar.set(Calendar.MILLISECOND, 0);

        return (int) ((toCalendar.getTime().getTime() - fromCalendar.getTime().getTime()) / (1000 * 60 * 60 * 24));
    }
    
     /**    
      * 得到几天前的时间    
      *     
      * @param d    
      * @param day    
      * @return    
      */     
     public static Date getDateBefore(Date d, int day) {      
         Calendar now = Calendar.getInstance();      
         now.setTime(d);      
         now.set(Calendar.DATE, now.get(Calendar.DATE) - day);      
         return now.getTime();      
     }     
     /**    
      * 得到几天后的时间    
      *     
      * @param d    
      * @param day    
      * @return    
      */     
     public static Date getDateAfter(Date d, int day) {      
        Calendar now = Calendar.getInstance();      
         now.setTime(d);      
         now.set(Calendar.DATE, now.get(Calendar.DATE) + day);      
         return now.getTime();      
     }   
     
      /**    
       * 得到几分前的时间    
       *     
       * @param d    
       * @param day    
       * @return    
       */     
      public static Date getMinuteBefore(Date d, int minute) {      
          Calendar now = Calendar.getInstance();      
          now.setTime(d);      
          now.set(Calendar.MINUTE, now.get(Calendar.MINUTE) - minute);      
          return now.getTime();      
      }     
      /**    
       * 得到几分后的时间    
       *     
       * @param d    
       * @param day    
       * @return    
       */     
      public static Date getMinuteAfter(Date d, int minute) {      
         Calendar now = Calendar.getInstance();      
          now.setTime(d);      
         now.set(Calendar.MINUTE, now.get(Calendar.MINUTE) + minute);      
          return now.getTime();      
      }   
      
      /**    
       * 得到几个月前的时间    
       *     
       * @param d    
       * @param day    
       * @return    
       */     
      public static Date getMonthBefore(Date d, int month) {      
          Calendar now = Calendar.getInstance();      
          now.setTime(d);      
          now.set(Calendar.MONTH, now.get(Calendar.MONTH) - month);      
          return now.getTime();      
      }     
      /**    
       * 得到几个月后的时间    
       *     
       * @param d    
       * @param day    
       * @return    
       */     
      public static Date getMonthAfter(Date d, int month) {      
         Calendar now = Calendar.getInstance();      
          now.setTime(d);      
         now.set(Calendar.MONTH, now.get(Calendar.MONTH) + month);      
          return now.getTime();      
      }   
      
      /**    
       * 得到几年前的时间    
       *     
       * @param d    
       * @param day    
       * @return    
       */     
      public static Date getYearBefore(Date d, int year) {      
          Calendar now = Calendar.getInstance();      
          now.setTime(d);      
          now.set(Calendar.YEAR, now.get(Calendar.YEAR) - year);      
          return now.getTime();      
      }     
      /**    
       * 得到几年后的时间    
       *     
       * @param d    
       * @param day    
       * @return    
       */     
      public static Date getYearAfter(Date d, int year) {      
         Calendar now = Calendar.getInstance();      
          now.setTime(d);      
         now.set(Calendar.YEAR, now.get(Calendar.YEAR) + year);      
          return now.getTime();      
      }   
}
